package com.sparrow.common.deadlock;

import com.google.common.util.concurrent.CycleDetectingLockFactory;
import java.util.concurrent.locks.Lock;

public class CycleDetectingLockExample {
    public static void main(String[] args) {
        CycleDetectingLockFactory factory = CycleDetectingLockFactory.newInstance(CycleDetectingLockFactory.Policies.THROW);

        Lock lock1 = factory.newReentrantLock("Lock1");
        Lock lock2 = factory.newReentrantLock("Lock2");

        Thread thread1 = new Thread(() -> {
            lock1.lock();
            try {
                System.out.println("Thread 1 acquired Lock1");
                // Simulate work before trying to acquire lock2
                Thread.sleep(2000);  // Increase sleep to force deadlock
                lock2.lock();
                try {
                    System.out.println("Thread 1 acquired Lock2");
                } finally {
                    lock2.unlock();
                }
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            } finally {
                lock1.unlock();
            }
        });

        Thread thread2 = new Thread(() -> {
            lock2.lock();
            try {
                System.out.println("Thread 2 acquired Lock2");
                // Simulate work before trying to acquire lock1
                Thread.sleep(2000);  // Increase sleep to force deadlock
                lock1.lock();
                try {
                    System.out.println("Thread 2 acquired Lock1");
                } finally {
                    lock1.unlock();
                }
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            } finally {
                lock2.unlock();
            }
        });

        thread1.start();
        thread2.start();

        try {
            thread1.join();
            thread2.join();
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }
}

